

//****************************************************************
var swSortConfig = new Object();

swSortConfig.currentJSON = new Object();
swSortConfig.currentJSON.shortname = "";
swSortConfig.currentJSON.category = "";
swSortConfig.currentJSON.subcategory = "";
swSortConfig.currentJSON.json_gallery_id = "";
swSortConfig.currentJSON.json_gallery_key = "";
swSortConfig.currentJSON.prev_category = "";
swSortConfig.currentJSON.prev_subcategory = "";
swSortConfig.currentJSON.prev_json_gallery_id = "";
swSortConfig.currentJSON.prev_json_gallery_key = "";

//the complete json object contains the whole json read
//from the according json gallery
swSortConfig.currentJSON.comp_json_object = new Object();
//the detail json block contains the currently relevant
//block of the complete json
swSortConfig.currentJSON.detail_json_block = new Object();

swSortConfig.deleteDef = new Object();
swSortConfig.deleteDef.section_id = "";
swSortConfig.deleteDef.section_text = "";

swSortConfig.createDef = new Object();
swSortConfig.createDef.section_id = "";
swSortConfig.createDef.section_text = "";
//****************************************************************




//**************************************************
//***swStartConfig
//***
//***This function starts the config tool.
//**************************************************
function swStartConfig(){
  
  swSortConfigLogin();
  
  //assign click handler to Definitions/Assignements Buttons
  $('#btnDefinitions').click(swShowDefinitions);
  $('#btnAssignements').click(swShowAssignements);
  $('#btnMain').click(swShowMain);
  $('#btnSave').click(swSaveJSONToGallery);
  $('#btnDelete').click(swDeleteJSONSettingsBlock);
  $('#btnCleanup').click(swCleanupJSONObject);
  
  //assign event handler to main config fields/checkboxes
  $('#new_main_title').focusout(function(){
    swSortConfig.currentJSON.detail_json_block.settings.title = $('#new_main_title').val();
  });
  $('#new_main_comment').focusout(function(){
      swSortConfig.currentJSON.detail_json_block._comment = $('#new_main_comment').val();
  });
  $('#main_category').focusout(function(){
      swSortConfig.currentJSON.detail_json_block._comment = $('#main_category').val();
  });
  $('#main_subcategory').focusout(function(){
      swSortConfig.currentJSON.detail_json_block._comment = $('#main_subcategory').val();
  });
  $('#new_main_crt_unsorted_sec').click(function(){
    if ($('#new_main_crt_unsorted_sec').attr('checked') == true){
      swSortConfig.currentJSON.detail_json_block.settings.create_unsorted_section = "true";
    } else {
      swSortConfig.currentJSON.detail_json_block.settings.create_unsorted_section = "false";
    }
  });
  $('#new_main_hide_empty_sec').click(function(){
    if ($('#new_main_hide_empty_sec').attr('checked') == true){
      swSortConfig.currentJSON.detail_json_block.settings.hide_empty_sections = "true";
    } else {
      swSortConfig.currentJSON.detail_json_block.settings.hide_empty_sections = "false";
    }
  });
  $('#new_main_hide_orig_gall_box').click(function(){
    if ($('#new_main_hide_orig_gall_box').attr('checked') == true){
      swSortConfig.currentJSON.detail_json_block.settings.hide_original_galleries_box_if_empty = "true";
    } else {
      swSortConfig.currentJSON.detail_json_block.settings.hide_original_galleries_box_if_empty = "false";
    }
  });
  $('#new_main_hide_orig_subcat_box').click(function(){
    if ($('#new_main_hide_orig_subcat_box').attr('checked') == true){
      swSortConfig.currentJSON.detail_json_block.settings.hide_original_subcat_box_if_empty = "true";
    } else {
      swSortConfig.currentJSON.detail_json_block.settings.hide_original_subcat_box_if_empty = "false";
    }
  });
  
  
  //hide all we don't need yet
  $('#configTabsBox').hide();
  $('#configBoxBottom').hide();
  $('#configMainTab').hide();
  
  //first build the JSON Tabs
  swBuildJSONTabs();
  //assign a click handler to the tabs
  $('.selectJSONTab').click(swSelectJSONTab);
  
  //we hide the save/delete button until the shortname is selected
  $('#footerBox').hide();

} //end of swStartConfig


//**************************************************
//***swSortConfigLogin
//***
//***This function logs in using an existing session.
//***If no session exists a new one is created
//***anonymously
//**************************************************
function swSortConfigLogin(){
  //get a session ID using an AJAX call
  //first try to login with session
  $.getJSON("/services/api/json/1.2.2/?method=smugmug.login.withSession&APIKey=b65LbayWryydERbvo9mwPLC6bkr7DJ8s",
    {
  
    },
    function(data) {
      //This is the callback function where we go on with processing
      if (swSortConstants.verbose == true){
        console.log("info: API call " + data.method + " " + data.stat);
      }
      if (data.stat === "ok"){
        //console.log("The Session ID is " + data.Login.Session.id);
      }
  
      //if the login withSession was not successfully we login anonymously as fallback
      if (data.stat.toLowerCase() === "fail"){
        if (swSortConstants.verbose == true){
          console.log("login failed...trying anonymous login...");
        }
        //we login anonymously sync because the album_fetch function shall not start before
        //the login call is finished
        swLogin_anonymously_sync();
      }
    });
} //end of function swSortConfigLogin




//**************************************************
//***swBuildJSONTabs
//***
//***This function reads the whole JSON customizing
//***and creates a tab for each JSON main element
//***(note: in a JSON gallery the customizing of
//**************************************************
function swBuildJSONTabs(){

  //find the tabs box
  var selectJsonBox = $('#selectJSONBox');
  

  //*** for each defined section-customizing-block we create a tab
  for (curr_key in swSortConstants.relevantCategories){
    
    //create a new tab using the curr_key as ID and text
    selectJsonBox.append('<span id="' + curr_key + '"><button>' + curr_key + '</button></span>');
    var curr_tab = $('#' + curr_key);
    //add the selectJSONTab class
    curr_tab.addClass("selectJSONTab");
    
  }
  
} //end of fucntion swBuildJSONTabs


//**************************************************
//***swSelectJSONTab
//***
//***This function selects the clicked button/tab
//***Technically the currentJSON variables are set
//**************************************************
function swSelectJSONTab(){

  if (swSortConstants.verbose == true){
    console.log(this.id + " clicked");
  }
  
  //first we make a backup of the old values
  swSortConfig.currentJSON.prev_shortname = swSortConfig.currentJSON.prev_shortname;
  swSortConfig.currentJSON.prev_category = swSortConfig.currentJSON.category;
  swSortConfig.currentJSON.prev_subcategory = swSortConfig.currentJSON.subcategory;
  swSortConfig.currentJSON.prev_json_gallery_id = swSortConfig.currentJSON.json_gallery_id;
  swSortConfig.currentJSON.prev_json_gallery_key = swSortConfig.currentJSON.json_gallery_key;

  //set the currentJSON variable
  //(the ID of the button equals the individual name of the definition
  swSortConfig.currentJSON.shortname = this.id;
  swSortConfig.currentJSON.category = swSortConstants.relevantCategories[this.id].category;
  swSortConfig.currentJSON.subcategory = swSortConstants.relevantCategories[this.id].subcategory;
  swSortConfig.currentJSON.json_gallery_id = swSortConstants.relevantCategories[this.id].json_gallery_id;
  swSortConfig.currentJSON.json_gallery_key = swSortConstants.relevantCategories[this.id].json_gallery_key;

  if (swSortConstants.verbose == true){
    console.log("now the currenJSON is:");
    console.log("shortname: " + swSortConfig.currentJSON.shortname);
    console.log("category: " + swSortConfig.currentJSON.category);
    console.log("sub category: " + swSortConfig.currentJSON.subcategory);
    console.log("json_gallery_id: " + swSortConfig.currentJSON.json_gallery_id);
    console.log("json_gallery_key: " + swSortConfig.currentJSON.json_gallery_key);
  }
  
  //if the JSON customizing comes from another json_gallery than the
  //previous json_gallery we re-load it. If the json_gallery equals no reloading is required
  if (swSortConfig.currentJSON.prev_json_gallery_id != swSortConfig.currentJSON.json_gallery_id &&
      swSortConfig.currentJSON.prev_json_gallery_key != swSortConfig.currentJSON.json_gallery_key){
      
    swWriteMessage("JSON gallery changed...reloading JSON.");
      
    if (swSortConstants.verbose == true){
      console.log("new json_gallery_id: " + swSortConfig.currentJSON.json_gallery_id);
      console.log("new json_gallery_key: " + swSortConfig.currentJSON.json_gallery_key);
    }
    
    //***initialize the detail_json_block
    swSortConfig.currentJSON.detail_json_block = null;
    swSortConfig.currentJSON.comp_json_object = null;
      
    if (swSortConstants.verbose == true){
      console.log("info: JSON gallery changed...reloading JSON");
    }
    
    //***try to load an existing JSON settings object
    swLoadJSON();
    
    //***if no comp JSON was found we need to create a new (empty) one
    if (swSortConfig.currentJSON.comp_json_object == null){
      console.log("creating new comp_json_object");
      swCreateNewCompJSON();
    }
    
    if (swSortConstants.verbose == true){
      console.dir(swSortConfig.currentJSON.comp_json_object);
    }
    
  } else {
  
    if (swSortConstants.verbose == true){
      console.log("info: JSON gallery did not change...no reloading required");
    }
    
  } //end of if prev_json_gallery_id changed
  
  //***we update the detail_json_block
  swFindDetailJSONBlock();
  
  //***check if we found an existing json (if the detail_json_block is filled).
  //***If not we need to create a new empty one
  
  if (swSortConfig.currentJSON.detail_json_block.settings != null){
    //we found an existing json
    swClearMessageBox();
    swWriteMessage("JSON Settings found and loaded.");
    
    //write the Title into the titleBox
    $('#selectJSONBoxTitle').text(this.id + " - " + swSortConfig.currentJSON.detail_json_block.settings.title);
    
    //show what is relevant
    $('#configTabsBox').show();
    $('#configBoxBottom').hide();
    $('#configMainTab').hide();
  
  } else {
    //we didn't find an existing detail json...so create a new one
    
    swWriteMessage("No JSON Settings found.");
    
    var new_id = swSortConfig.currentJSON.comp_json_object.length;
    
    //build the required JSON Objects
    swSortConfig.currentJSON.comp_json_object[new_id] = new Object();
    swSortConfig.currentJSON.comp_json_object[new_id].category = swSortConfig.currentJSON.category;
    if (swSortConfig.currentJSON.subcategory == null){
      swSortConfig.currentJSON.comp_json_object[new_id].subcategory = "";
    } else {
      swSortConfig.currentJSON.comp_json_object[new_id].subcategory = swSortConfig.currentJSON.subcategory;
    }
    swSortConfig.currentJSON.comp_json_object[new_id].settings = new Object();
    swSortConfig.currentJSON.comp_json_object[new_id].settings.section_assignements = new Array;
    swSortConfig.currentJSON.comp_json_object[new_id].settings.section_definitions = new Array;
    
    if (swSortConstants.verbose == true){
      console.dir(swSortConfig.currentJSON.comp_json_object);
    }
    
    //***try again to find the (new) json block
    swFindDetailJSONBlock();
    
    $('#selectJSONBoxTitle').text(this.id);
    
    //show what is relevant
    $('#configTabsBox').show();
    $('#configBoxBottom').hide();
    $('#configMainTab').hide();
    
    swWriteMessage("New JSON Settings block created.");
  }
  
  //now show the save/delete button
  $('#footerBox').show();
  
} //end of function swSelectJSONTab



//**************************************************
//***swCreateNewCompJSON
//***
//***This function creates a new empty complete JSON
//***settings block
//**************************************************
function swCreateNewCompJSON(){

  swSortConfig.currentJSON.comp_json_object = new Array;

}



//**************************************************
//***swLoadJSON
//***
//***This function loads the JSON by making an
//***async API call
//**************************************************
function swLoadJSON(){

  var gallery_id = swSortConfig.currentJSON.json_gallery_id;
  var gallery_key = swSortConfig.currentJSON.json_gallery_key;

  swSortConfig.currentJSON.comp_json_object = swGetGalleryJSONAsync(gallery_id, gallery_key);

} //end of function swLoadJSON



//**************************************************
//***swFindDetailJSONBlock
//***
//***This function finds the relevant settings block
//***in the complete JSON. The relevant block is
//***written into swSortConfig.currentJSON.detail_json_block
//**************************************************
function swFindDetailJSONBlock(){
  
  if (swSortConfig.currentJSON.comp_json_object == null){
    console.log("Error: swSortConfig.currentJSON.comp_json_object is null but needs to be filled");
    console.log("Error: Use function swLoadJSON to load a comp_json_object");
  }
  
  //in the current json object there can be multiple shortname/definition blocks
  //so first we need to find out the correct one by comparing the category/sub category
  for (curr_key in swSortConfig.currentJSON.comp_json_object){
  
    var curr_json = swSortConfig.currentJSON.comp_json_object[curr_key];
    
    //if we find undefined sub categores in the JSON we set it as an empty string
    if (swSortConfig.currentJSON.subcategory == null){
      swSortConfig.currentJSON.subcategory = "";
    }
    
    //console.log(curr_key);
    //console.log(swSortConfig.currentJSON.category);
    //console.log(curr_json.category);
    //console.log(swSortConfig.currentJSON.subcategory);
    //console.log(curr_json.subcategory);
    
    if (curr_json.category == swSortConfig.currentJSON.category &&
        curr_json.subcategory == swSortConfig.currentJSON.subcategory){

      swSortConfig.currentJSON.detail_json_block = curr_json;
      if (swSortConstants.verbose == true){
        console.log("info: relevant JSON block found");
        console.dir(swSortConfig.currentJSON.detail_json_block);
      }
      
    }
  
  }
  
  //at this point we should have found a detail_json_block
  //if not we need to create a new one
  if (swSortConfig.currentJSON.detail_json_block == null){
    swWriteMessage("No corresponding detail_json_block found...creating new one.");
    
    var new_key = swSortConfig.currentJSON.comp_json_object.length;
    swSortConfig.currentJSON.comp_json_object[new_key] = new Object;
    swSortConfig.currentJSON.comp_json_object[new_key].category = swSortConfig.currentJSON.category;
    if (swSortConfig.currentJSON.subcategory == null){
      swSortConfig.currentJSON.comp_json_object[new_key].subcategory = "";
    } else {
      swSortConfig.currentJSON.comp_json_object[new_key].subcategory = swSortConfig.currentJSON.subcategory;
    }
    swSortConfig.currentJSON.comp_json_object[new_key].settings = new Object;
    swSortConfig.currentJSON.comp_json_object[new_key].settings.section_definitions = new Array;
    swSortConfig.currentJSON.comp_json_object[new_key].settings.section_assignements = new Array;
    
    //set the new block as the detail_json_block
    swSortConfig.currentJSON.detail_json_block = swSortConfig.currentJSON.comp_json_object[new_key];
  }

} //end of function swFindDetailJSONBlock


//**************************************************
//***swWriteMessage
//***
//***This function writes a message to the messageBox
//**************************************************
function swWriteMessage(messageText){

  $('#messageBox').append("<p>" + messageText + "</p>");

} //end of swWriteMessage

//**************************************************
//***swClearMessageBox
//***
//***This function clears the messageBox
//**************************************************
function swClearMessageBox(){
  
  $('#messageBox > p').remove();
  
} //end of swClearMessageBox



//**************************************************
//***swShowDefinitions
//***
//***This function shows the section definitons
//***to the current JSON shortname
//**************************************************
function swShowDefinitions(){
  
  if (swSortConfig.currentJSON.shortname != ""){
    
    if (swSortConstants.verbose == true){
      console.log("info: show Definitions for " + swSortConfig.currentJSON.shortname);
    }
    
    swBuildDefinitionsTable();
  
    //show what is relevant
    //$('#configTabsBox').show();
    $('#configMainTab').hide();
    $('#configBoxBottom').show();
    
  
  } else {
    alert("no settings block selected.");
  }

} //end of function swShowDefinitions



//**************************************************
//***swShowAssignements
//***
//***This function shows the assignements to the
//***current JSON shortname
//**************************************************
function swShowAssignements(){

  if (swSortConfig.currentJSON.shortname != ""){
    
    if (swSortConstants.verbose == true){
      console.log("info: show Assignements for " + swSortConfig.currentJSON.shortname);
    }
    
    swBuildAssignementsTable();

    //show what is relevant
    //$('#configTabsBox').show();
    $('#configMainTab').hide();
    $('#configBoxBottom').show();
  
  } else {
    alert("no settings block selected.");
  }

} //end of function swShowAssignements



//**************************************************
//***swShowMain
//***
//***This function shows the main config box to the
//***current JSON shortname
//**************************************************
function swShowMain(){

  if (swSortConfig.currentJSON.shortname != ""){
    
    if (swSortConstants.verbose == true){
     console.log("info: show main config for " + swSortConfig.currentJSON.shortname);
    }
    
    swClearMessageBox();
    
    //fill the text fields and checkboxes
    swFillMainConfigFields();

    //show what is relevant
    //$('#configTabsBox').show();
    $('#configBoxBottom').hide();
    $('#configMainTab').show();
  
  } else {
    alert("no settings block selected.");
  }

} //end of function swShowMain



//**************************************************
//***swFillMainConfigFields
//***
//***This function fills the main config values from
//***the current JSON settings block into the dialog
//***fields
//**************************************************
function swFillMainConfigFields(){

  $('#new_main_title').val(swSortConfig.currentJSON.detail_json_block.settings.title);
  $('#new_main_comment').val(swSortConfig.currentJSON.detail_json_block._comment);
  $('#main_category').val(swSortConfig.currentJSON.detail_json_block.category);
  $('#main_subcategory').val(swSortConfig.currentJSON.detail_json_block.subcategory);
  
  //checkbox Create Unsorted Section
  if (swSortConfig.currentJSON.detail_json_block.settings.create_unsorted_section == "true"){
    $('#new_main_crt_unsorted_sec').attr('checked', true);
  } else {
    $('#new_main_crt_unsorted_sec').attr('checked', false);
  }
  
  //checkbox Hide Empty Sections
  if (swSortConfig.currentJSON.detail_json_block.settings.hide_empty_sections == "true"){
    $('#new_main_hide_empty_sec').attr('checked', true);
  } else {
    $('#new_main_hide_empty_sec').attr('checked', false);
  }
  
  //checkbox Hide Original Galleries Box If Empty
  if (swSortConfig.currentJSON.detail_json_block.settings.hide_original_galleries_box_if_empty == "true"){
    $('#new_main_hide_orig_gall_box').attr('checked', true);
  } else {
    $('#new_main_hide_orig_gall_box').attr('checked', false);
  }
  
  //checkbox Hide Original Subcat Box If Empty
  if (swSortConfig.currentJSON.detail_json_block.settings.hide_original_subcat_box_if_empty == "true"){
    $('#new_main_hide_orig_subcat_box').attr('checked', true);
  } else {
    $('#new_main_hide_orig_subcat_box').attr('checked', false);
  }
  

} //end of function swFillMainConfigFields




//**************************************************
//***swBuildDefinitionsTable
//***
//***This function builds the Definitions Table
//***using the detail_json_block variable
//**************************************************
function swBuildDefinitionsTable(){
  
  swClearMessageBox();
  
  //***remove event handler from all already existing buttons (we will add them again later)
  $('.btnDelDef').unbind("click");

  //***delete existing rows
  $('#configBoxBottomTable tr').remove();
  
  //***create new rows for each section definition
  var def_table = $('#configBoxBottomTable');
  
  //create the table header
  def_table.append("<tr class=\"defTabHeadline\"><th class=\"defTabHeadCell\" colspan=\"2\">&nbsp;</th><th class=\"defTabHeadCell\">SeqID</th><th class=\"defTabHeadCell\">Section ID</th><th class=\"defTabHeadCell\">Section Text</th></tr>");
  
  for (curr_key in swSortConfig.currentJSON.detail_json_block.settings.section_definitions){
  
    curr_def = swSortConfig.currentJSON.detail_json_block.settings.section_definitions[curr_key];
    
    //append a row to the def_table
    //def_table.append("<tr><td>" + curr_def.section_id + "</td><td>" + curr_def.section_text + "</td><td><button id=\"del_" + curr_def.section_id + "\" class=\"btnDelDef\">Delete</button></td></tr>");
    //var new_btn = $('#del_' + curr_def.section_id);
    //new_btn.bind("click", {"section_id": curr_def.section_id}, swDeleteDefinition);
    
  }
  
  var hits = 0;
  var curr_seq = 0;
  if (swSortConstants.verbose == true){
    console.log("detail_json_block in swBuildDefinitionsTable");
    console.dir(swSortConfig.currentJSON.detail_json_block);
  }
  
  while (hits < swSortConfig.currentJSON.detail_json_block.settings.section_definitions.length){
    
    //console.log("curr_seq: " + curr_seq);
    
    //check if we find a corresponding sequence_id in the definitions array
    for (curr_key in swSortConfig.currentJSON.detail_json_block.settings.section_definitions){
    
      var curr_def = swSortConfig.currentJSON.detail_json_block.settings.section_definitions[curr_key];
      if (curr_def.sequence_id != null){
      
        if (curr_def.sequence_id == curr_seq){
          //console.log("info: hit!!! sequence_id and curr_seq match.");
          hits++;
          
          //append a row to the def_table
          def_table.append("<tr class=\"defTabRow\"></tr>");
          var def_table_tr = $('#configBoxBottomTable > tbody > tr:last');
          def_table_tr.append("<td class=\"defTabCell\"><button id=\"up_" + curr_def.section_id + "\">up</button></td>");
          def_table_tr.append("<td class=\"defTabCell\"><button id=\"down_" + curr_def.section_id + "\">down</button></td>");
          def_table_tr.append("<td class=\"defTabCell\">" + curr_def.sequence_id + "</td>");
          def_table_tr.append("<td class=\"defTabCell\">" + curr_def.section_id + "</td>");
          def_table_tr.append("<td class=\"defTabCell\">" + curr_def.section_text + "</td>");
          def_table_tr.append("<td class=\"defTabCell\"><button id=\"del_" + curr_def.section_id + "\" class=\"btnDelDef\">Delete</button></td>");
          
          var del_btn = $('#del_' + curr_def.section_id);
          del_btn.bind("click", {"section_id": curr_def.section_id}, swDeleteDefinition);
          var up_btn = $('#up_' + curr_def.section_id);
          up_btn.bind("click", {"section_id": curr_def.section_id}, swMoveDefinitionUp);
          var down_btn = $('#down_' + curr_def.section_id);
          down_btn.bind("click", {"section_id": curr_def.section_id}, swMoveDefinitionDown);
          
        } else {
          //console.log("info: no hit");
        }
      
      } else {
        console.log("warning: no sequence id defined at definition " + curr_def.section_id);
        console.log("warning: setting curr_seq " + curr_seq + " as sequence_id");
        console.log("warning: please click the button again");
        curr_def.sequence_id = curr_seq;
        
        swClearMessageBox();
        swWriteMessage("New Sequence IDs set...please click the Definitions button again.");
        
        hits++;
        break;
      }
    
    }
    
    curr_seq++;
    
  } //end of while
  
  //***create one line for new sections
  var def_table = $('#configBoxBottomTable');
  def_table.append("<tr class=\"defTabRow\"><td class=\"defTabCell\" colspan=\"3\">&nbsp;</td><td class=\"defTabCell\"><input type=text id=new_section_id></input></td><td class=\"defTabCell\"><input type=text id=new_section_text></input></td><td class=\"defTabCell\"><button id=\"btnNewDef\">Create</button></td></tr>");
  $('#btnNewDef').click(swCreateDefinition);

} //end of function swBuildDefinitionsTable




//**************************************************
//***swBuildAssignementsTable
//***
//***This function builds the Assignements Table
//***using the detail_json_block variable
//**************************************************
function swBuildAssignementsTable(){
  
  swClearMessageBox();
  
  //***remove event handler from all already existing buttons (we will add them again later)
  $('.btnDelAsg').unbind("click");

  //***delete existing rows
  $('#configBoxBottomTable tr').remove();
  
  //***create new rows for each section definition
  var asg_table = $('#configBoxBottomTable');
  
  //create the table header
  asg_table.append("<tr class=\"asgTabHeadline\"></tr>");
  var asg_table_head = $('#configBoxBottomTable > tbody > tr:first');
  asg_table_head.append("<th class=\"asgTabHeadCell\" colspan=\"2\">&nbsp;</th>");
  asg_table_head.append("<th class=\"asgTabHeadCell\">SeqID</th>");
  asg_table_head.append("<th class=\"asgTabHeadCell\">Section</th>");
  asg_table_head.append("<th class=\"asgTabHeadCell\">Gallery ID</th>");
  asg_table_head.append("<th class=\"asgTabHeadCell\">Sub Category ID</th>");
  asg_table_head.append("<th class=\"asgTabHeadCell\">Category ID</th>");
  asg_table_head.append("<th class=\"asgTabHeadCell\">Comment</th>");
  
 
  var hits = 0;
  var curr_seq = 0;
  
  while (hits < swSortConfig.currentJSON.detail_json_block.settings.section_assignements.length){
    
    //console.log("curr_seq: " + curr_seq);
    
    //check if we find a corresponding sequence_id in the definitions array
    for (curr_key in swSortConfig.currentJSON.detail_json_block.settings.section_assignements){
    
      var curr_asg = swSortConfig.currentJSON.detail_json_block.settings.section_assignements[curr_key];
      if (curr_asg.sequence_id != null){
      
        if (curr_asg.sequence_id == curr_seq){
          //console.log("info: hit!!! sequence_id and curr_seq match.");
          hits++;
          
          //append a row to the asg_table
          asg_table.append("<tr class=\"asgTabRow\"></tr>");
          var asg_table_tr = $('#configBoxBottomTable > tbody > tr:last');
          asg_table_tr.append("<td class=\"asgTabCell\"><button id=\"up_" + curr_asg.sequence_id + "\">up</button></td>");
          asg_table_tr.append("<td class=\"asgTabCell\"><button id=\"down_" + curr_asg.sequence_id + "\">down</button></td>");
          asg_table_tr.append("<td class=\"asgTabCell\">" + curr_asg.sequence_id + "</td>");
          asg_table_tr.append("<td class=\"asgTabCell\">" + curr_asg.section_id + "</td>");
          if (curr_asg.gallery_id != null){
            asg_table_tr.append("<td class=\"asgTabCell asgTabCellGalleryId\">" + curr_asg.gallery_id + "</td>");
          } else {
            asg_table_tr.append("<td class=\"asgTabCell\">&nbsp;</td>");
          }
          if (curr_asg.subcat_id != null){
            asg_table_tr.append("<td class=\"asgTabCell\">" + curr_asg.subcat_id + "</td>");
          } else {
	    asg_table_tr.append("<td class=\"asgTabCell\">&nbsp;</td>");
          }
          if (curr_asg.category_id != null){
            asg_table_tr.append("<td class=\"asgTabCell\">" + curr_asg.category_id + "</td>");
          } else {
	    asg_table_tr.append("<td class=\"asgTabCell\">&nbsp;</td>");
          }
          asg_table_tr.append("<td class=\"asgTabCell\">" + curr_asg._comment + "</td>");
          asg_table_tr.append("<td class=\"asgTabCell\"><button id=\"del_" + curr_asg.sequence_id + "\" class=\"btnDelAsg\">Delete</button></td>");
          
          var del_btn = $('#del_' + curr_asg.sequence_id);
          del_btn.bind("click", {"sequence_id": curr_asg.sequence_id}, swDeleteAssignement);
          var up_btn = $('#up_' + curr_asg.sequence_id);
          up_btn.bind("click", {"sequence_id": curr_asg.sequence_id}, swMoveAssignementUp);
          var down_btn = $('#down_' + curr_asg.sequence_id);
          down_btn.bind("click", {"sequence_id": curr_asg.sequence_id}, swMoveAssignementDown);
          
        } else {
          //console.log("info: no hit");
        }
      
      } else {
        console.log("warning: no sequence id defined at assignement " + curr_asg.gallery_id);
        console.log("warning: setting curr_seq " + curr_seq + " as sequence_id");
        console.log("warning: please click the button again");
        curr_asg.sequence_id = curr_seq;
        
        swClearMessageBox();
        swWriteMessage("New Sequence IDs set...please click the Assignements button again.");
        
        hits++;
        break;
      }
    
    }
    
    curr_seq++;
    
  }
  
  //***Enhance Gallery IDs with Descriptions
  swEnhanceGalleryIdWithDesc();
  
    //***create one line for new assignement
    var asg_table = $('#configBoxBottomTable');
    asg_table.append("<tr class=\"asgTabRow\"></tr>");
    var asg_table_tr = $('#configBoxBottomTable > tbody > tr:last');
    
    asg_table_tr.append("<td class=\"asgTabCell\" colspan=\"3\">&nbsp;</td>");
    
    //asg_table_tr.append("<td class=\"asgTabCell\"><input type=text id=new_section_id></input></td>");
    asg_table_tr.append("<select id=\"new_section_id\"></select");
    var section_id_select = $('#new_section_id');
    for (curr_key in swSortConfig.currentJSON.detail_json_block.settings.section_definitions){
      var curr_def = swSortConfig.currentJSON.detail_json_block.settings.section_definitions[curr_key];
      section_id_select.append("<option value=\"" + curr_def.section_id + "\">" + curr_def.section_text + " (" + curr_def.section_id + ")</option>");
    }
    
    /*
    asg_table_tr.append("<td class=\"asgTabCell\"><input type=text id=\"new_gallery_id\"></input></td>");
    asg_table_tr.append("<td class=\"asgTabCell\"><input type=text id=\"new_subcat_id\"></input></td>");
    asg_table_tr.append("<td class=\"asgTabCell\"><input type=text id=\"new_category_id\"></input></td>");
    asg_table_tr.append("<td class=\"asgTabCell\"><input type=text id=\"new_comment\"></input></td>");
    asg_table_tr.append("<td class=\"asgTabCell\"><button id=\"btnNewAsg\">Create</button></td>");
    
    //add event handler to the gallery_id/subcat_id/category_id fields
    //if any field is changed the two others are cleared. It is not allowed
    //to enter values into more than one field
    $('#new_gallery_id').keydown(function(){
      $('#new_subcat_id').val("");
      $('#new_category_id').val("");
    });
    $('#new_subcat_id').keydown(function(){
          $('#new_gallery_id').val("");
          $('#new_category_id').val("");
    });
    $('#new_category_id').keydown(function(){
          $('#new_gallery_id').val("");
          $('#new_subcat_id').val("");
    });
    */
    
    //***Gallery ID Combo Box
    asg_table_tr.append("<td class=\"asgTabCell\"><select id=\"new_gallery_id\"></select></td>");
    var gallery_id_select = $('#new_gallery_id');
    //now get the options for the select box by an ajax call
    //(coding for showing the options is in the callback function of the ajax call
    $.getJSON("/services/api/json/1.2.2/?method=smugmug.albums.get",
      {
    
      },
      function(data) {
        //This is the callback function where we go on with processing
        if (data.stat === "ok"){
          //now sort the albums by category_id
          data.Albums.sort(swSortAlbumsByCategoryID);
          //console.dir(data.Albums);
          var prev_cat_id = -1;
          gallery_id_select.append("<option value=\"\"></option>");
          for (curr_key in data.Albums){
            var curr_album = data.Albums[curr_key];
            if (curr_album.Category.id != prev_cat_id){
              gallery_id_select.append("<option value=\"-\">---" + curr_album.Category.Name + "---</option>");
            }
            gallery_id_select.append("<option value=\"" + curr_album.id + "\">" + curr_album.Title + "</option>");
            //remember the current category id as previous one
            prev_cat_id = curr_album.Category.id;
          }
        }
    
        //if the AJAX call failed write an error message
        if (data.stat.toLowerCase() === "fail"){
          swWriteMessage("Reading Galleries failed.");
        }
      }); //end of ajax call
    
    //***Sub Category Combo Box
    //asg_table_tr.append("<td class=\"asgTabCell\"><input type=text id=\"new_subcat_id\"></input></td>");
    asg_table_tr.append("<td class=\"asgTabCell\"><select id=\"new_subcat_id\"></select></td>");
    var subcat_id_select = $('#new_subcat_id');
    //now get the options for the select box by an ajax call
    //(coding for showing the options is in the callback function of the ajax call
    $.getJSON("/services/api/json/1.2.2/?method=smugmug.subcategories.getAll",
      {
    
      },
      function(data) {
        //This is the callback function where we go on with processing
        if (data.stat === "ok"){
          //now sort the albums by category_id
          data.SubCategories.sort(swSortSubcategoriesByCategoryID);
          //console.dir(data.SubCategories);
          var prev_cat_id = -1;
          subcat_id_select.append("<option value=\"\"></option>");
          for (curr_key in data.SubCategories){
            var curr_subcat = data.SubCategories[curr_key];
            if (curr_subcat.Category.id != prev_cat_id){
              subcat_id_select.append("<option value=\"-\">---" + curr_subcat.Category.Name + "---</option>");
            }
            subcat_id_select.append("<option value=\"" + curr_subcat.NiceName + "\">" + curr_subcat.NiceName + "</option>");
            //remember the current category id as previous one
            prev_cat_id = curr_subcat.Category.id;
          }
        }
    
        //if the AJAX call failed write an error message
        if (data.stat.toLowerCase() === "fail"){
          swWriteMessage("Reading Sub Categories failed.");
        }
      }); //end of ajax call
    
    //***Category Combo Box
    //asg_table_tr.append("<td class=\"asgTabCell\"><input type=text id=\"new_category_id\"></input></td>");
    asg_table_tr.append("<td class=\"asgTabCell\"><select id=\"new_category_id\"></select></td>");
    var cat_id_select = $('#new_category_id');
    //now get the options for the select box by an ajax call
    //(coding for showing the options is in the callback function of the ajax call
    $.getJSON("/services/api/json/1.2.2/?method=smugmug.categories.get",
      {
    
      },
      function(data) {
        //This is the callback function where we go on with processing
        if (data.stat === "ok"){
          //sort the categories descending
          data.Categories.sort(swSortCategoriesDesc);
          //console.dir(data.Categories);
          cat_id_select.append("<option value=\"\"></option>");
          for (curr_key in data.Categories){
            var curr_cat = data.Categories[curr_key];
            cat_id_select.append("<option value=\"" + curr_cat.NiceName + "\">" + curr_cat.NiceName + "</option>");
          }
        }
    
        //if the AJAX call failed write an error message
        if (data.stat.toLowerCase() === "fail"){
          swWriteMessage("Reading Categories failed.");
        }
      }); //end of ajax call
    
    
    asg_table_tr.append("<td class=\"asgTabCell\"><input type=text id=\"new_comment\"></input></td>");
    asg_table_tr.append("<td class=\"asgTabCell\"><button id=\"btnNewAsg\">Create</button></td>");
    
    //***add some events to the combo boxes
    $('#new_gallery_id').change(function(){
      $('#new_subcat_id').val("");
      $('#new_category_id').val("");
    });
    $('#new_subcat_id').change(function(){
      $('#new_gallery_id').val("");
      $('#new_category_id').val("");
    });
    $('#new_category_id').change(function(){
      $('#new_subcat_id').val("");
      $('#new_gallery_id').val("");
    });
    
    
    $('#btnNewAsg').click(swCreateAssignement);

} //end of function swBuildAssignementsTable


//**************************************************
//***swSortAlbumsByCategoryID
//***
//***This function sorts the galleries a and b
//***by their category id's
//**************************************************
function swSortAlbumsByCategoryID(a, b){
  
  return(a.Category.id - b.Category.id);
  
} //end of function swSortAlbumsByCategoryID

//**************************************************
//***swSortSubcategoriesByCategoryID
//***
//***This function sorts the sub categories a and by
//***by their category id's
//**************************************************
function swSortSubcategoriesByCategoryID(a, b){
  
  return(a.Category.id - b.Category.id);
  
} //end of function swSortSubcategoriesByCategoryID

//**************************************************
//***swSortCategoriesDesc
//***
//***This function sorts the categories a and by
//***descending by their id's
//**************************************************
function swSortCategoriesDesc(a, b){

  return(b.id - a.id);

} //end of function swSortCategoriesDesc


//**************************************************
//***swEnhanceGalleryIdWithDesc
//***
//***This function enhances gallery id's in the
//***assignements table with the Title information
//***of the corresponding gallery.
//***Therefore one additional AJAX call to
//***smugmug.albums.get is performed.
//**************************************************
function swEnhanceGalleryIdWithDesc(){

  if (swSortConstants.verbose == true){
    console.log("enhancing Gallery IDs with Gallery Titles");
    //console.dir($('.asgTabCellGalleryId'));
  }
  
  $.getJSON("/services/api/json/1.2.2/?method=smugmug.albums.get",
    {
  
    },
    function(data) {
      //This is the callback function where we go on with processing
      if (data.stat === "ok"){

        for (i=0; i<$('.asgTabCellGalleryId').length; i++){
          var curr_gallery_id = $('.asgTabCellGalleryId')[i].firstChild.wholeText;
          //console.log(curr_gallery_id);
          
          for (curr_key in data.Albums){
            if (data.Albums[curr_key].id == curr_gallery_id){
              curr_gallery_id = curr_gallery_id + " " + data.Albums[curr_key].Title;
              //console.log(curr_gallery_id);
              $('.asgTabCellGalleryId')[i].firstChild.nodeValue = curr_gallery_id;
            }
          }
        }

      } //end of is data.stat ok
  
      //if the AJAX call failed write an error message
      if (data.stat.toLowerCase() === "fail"){
        swWriteMessage("Reading Gallery Titles failed.");
      }
    }); //end of ajax call
  
} //end of function swEnhanceGalleryIdWithDesc

//**************************************************
//***swDeleteDefinition
//***
//***This function deletes a definition
//***The definition to be deleted is passed into the
//***function by the event parameter. The parameter
//***is defined in json format. The json content can
//***be found in event.data
//**************************************************
function swDeleteDefinition(event){

  if (swSortConstants.verbose == true){
    console.log("delete button pressed");
  }
  
  //clear messageBox
  swClearMessageBox();
  
  //console.dir(event);
  if (swSortConstants.verbose == true){
    console.log("section to delete: " + event.data.section_id);
  }
  
  //find the array key of the selected section_id
  var del_key = null;
  for (curr_key in swSortConfig.currentJSON.detail_json_block.settings.section_definitions){
    var curr_def = swSortConfig.currentJSON.detail_json_block.settings.section_definitions[curr_key];
    if (curr_def.section_id == event.data.section_id){
      del_key = curr_key;
    }
  }
  
  if (swSortConstants.verbose == true){
    console.dir(swSortConfig.currentJSON.detail_json_block.settings.section_definitions);
  }
  
  //now remove (splice removes the whole key instead only setting it to null)
  swSortConfig.currentJSON.detail_json_block.settings.section_definitions.splice(del_key,1);
  
  if (swSortConstants.verbose == true){
    console.log("section definition deleted");
    console.dir(swSortConfig.currentJSON.detail_json_block.settings.section_definitions);
  }
  
  //tell that we deleted
  swWriteMessage("Section Definition deleted");
  
  //rebuild the definitions table
  swBuildDefinitionsTable();
  
} //end of function swDeleteDefinition


//**************************************************
//***swCreateDefinition
//***
//***The id and text of the new definition is not passed
//***into the method via parameter. Actually the function
//***reads the according input fields directly
//**************************************************
function swCreateDefinition(){

  if (swSortConstants.verbose == true){
    console.log("save definition button pressed");
  }
  
  //clear messageBox
  swClearMessageBox();
  
  var new_section_id = $('#new_section_id').val();
  var new_section_text = $('#new_section_text').val();
  
  if (swSortConstants.verbose == true){
    console.log("section to create: " + new_section_id + " / " + new_section_text);
  }
  
  //first check if the new section_id already exists
  if (swDoesSectionDefinitionExist(new_section_id) == true){
    //section already exists...write a message
    //alert("An equal section_id already exists in this configuration block");
    swWriteMessage("An equal section_id already exists in this configuration block.");
    swWriteMessage("Please use another section_id");
    
  } else {
    //ok, section_id does not already exist, so we can go on
    
    //execute the create checks
    if (swDefinitionCreateChecks(new_section_id, new_section_text) == true){
    
      //find the highest seq id and raise it by one
      var highest_seq_id = 0;
      for (curr_key in swSortConfig.currentJSON.detail_json_block.settings.section_definitions){
        curr_def = swSortConfig.currentJSON.detail_json_block.settings.section_definitions[curr_key];
        if (curr_def.sequence_id > highest_seq_id){
          highest_seq_id = curr_def.sequence_id;
        }
      }
    
      //write the new definition into the detail block
      var next_key = swSortConfig.currentJSON.detail_json_block.settings.section_definitions.length;
    
      //if the next_key is undefined (might happen if no elements are in the definitions yet)
      //we set the next_key to 0
      if (next_key == null){
        next_key = 0;
      }
    
      swSortConfig.currentJSON.detail_json_block.settings.section_definitions[next_key] = new Object;
    
      swSortConfig.currentJSON.detail_json_block.settings.section_definitions[next_key].sequence_id = highest_seq_id + 1;
      swSortConfig.currentJSON.detail_json_block.settings.section_definitions[next_key].section_id = new_section_id;
      swSortConfig.currentJSON.detail_json_block.settings.section_definitions[next_key].section_text = new_section_text;
    
      if (swSortConstants.verbose == true){
        console.log("new section created.");
        console.dir(swSortConfig.currentJSON.detail_json_block);
        console.dir(swSortConfig.currentJSON.comp_json_object);
      }
    
    
      //tell that the new section definition was created
      swWriteMessage("New Section created.");
    
      //now rebuild the definitions table
      swBuildDefinitionsTable();
    
    }
    
  }

} //end of swCreateDefinition

//**************************************************
//***swDefinitionCreateChecks
//***
//***This function executes the create checks for
//***definitions and returns true if everything
//***is ok
//**************************************************
function swDefinitionCreateChecks(new_section_name, new_section_text){

  console.log("checking new section definition" + new_section_name);
  
  var no_error_found = true;
  
  //***check if id contains special characters
  //***Allowed is only A-Z and a-z and 0-9 and _
  var regex_result = new_section_name.match(/^[A-Za-z0-9_]+$/);
  console.log("regex_result: " + regex_result);
  if (regex_result == null){
    no_error_found = false;
    swWriteMessage("Error: You can only use characters, numbers and _ (underscore).");
  }
  
  
  return(no_error_found);

} //end of function swDefinitionCreateChecks



//**************************************************
//***swCreateAssignement
//***
//***The id and text of the new assignement is not passed
//***into the method via parameter. Actually the function
//***reads the according input fields directly
//**************************************************
function swCreateAssignement(){

  if (swSortConstants.verbose == true){
    console.log("create assignement");
  }
  
  //clear messageBox
  swClearMessageBox();
  
  var new_section_id = $('#new_section_id').val();
  var new_gallery_id = $('#new_gallery_id').val();
  var new_subcat_id = $('#new_subcat_id').val();
  var new_category_id = $('#new_category_id').val();
  var new_comment = $('#new_comment').val();
  
  //at least new_section_id and new_gallery_id needs to be filled
  if (new_section_id == null || new_section_id == "" ){
      
    //write error message
    swWriteMessage("Please provide a Section ID.");
    
  } else {
  
    if (swAssignementCreateChecks(new_section_id, new_gallery_id, new_subcat_id, new_category_id) == true){
    
      //ok, checks passed, so create assignement
    
      //find the highest seq id and raise it by one
      var highest_seq_id = 0;
      for (curr_key in swSortConfig.currentJSON.detail_json_block.settings.section_assignements){
        var curr_asg = swSortConfig.currentJSON.detail_json_block.settings.section_assignements[curr_key];
        if (curr_asg.sequence_id > highest_seq_id){
          highest_seq_id = curr_asg.sequence_id;
        }
      }
      
      //write the new assignement into the detail block
      var next_key = swSortConfig.currentJSON.detail_json_block.settings.section_assignements.length;
      swSortConfig.currentJSON.detail_json_block.settings.section_assignements[next_key] = new Object;
      
      swSortConfig.currentJSON.detail_json_block.settings.section_assignements[next_key].sequence_id = highest_seq_id + 1;
      
      swSortConfig.currentJSON.detail_json_block.settings.section_assignements[next_key].section_id = new_section_id;
      if (new_gallery_id != ""){
        swSortConfig.currentJSON.detail_json_block.settings.section_assignements[next_key].gallery_id = new_gallery_id;
      }
      if (new_subcat_id != ""){
        swSortConfig.currentJSON.detail_json_block.settings.section_assignements[next_key].subcat_id = new_subcat_id;
      }
      if (new_category_id != ""){
        swSortConfig.currentJSON.detail_json_block.settings.section_assignements[next_key].category_id = new_category_id;
      }
      
      swSortConfig.currentJSON.detail_json_block.settings.section_assignements[next_key]._comment = new_comment;
      
      if (swSortConstants.verbose == true){
        console.log("new assignement created.");
        console.dir(swSortConfig.currentJSON.detail_json_block);
        console.dir(swSortConfig.currentJSON.comp_json_object);
      }
      
      //tell that the new section definition was created
      swWriteMessage("New Assignement created.");
      
      //now rebuild the definitions table
      swBuildAssignementsTable();
    
    }
  
  }
  
} //end of function swCreateAssignement

//**************************************************
//***swAssignementCreateChecks
//***
//***This function executes the create checks for
//***definitions and returns true if everything
//***is ok
//**************************************************
function swAssignementCreateChecks(new_section_id, new_gallery_id, new_subcat_id, new_category_id){

  console.log("checking new section assignement");
  
  var no_error_found = true;
  
  //***check if exactly one field beside the section id is filled
  if (new_gallery_id != ""){
    if (new_subcat_id != "" ||
        new_category_id != ""){
      no_error_found = false;
      swWriteMessage("Please enter exactly one of the fields Gallery ID, Sub Category ID and Category ID");
    }
  }
  if (new_subcat_id != ""){
    if (new_gallery_id != "" ||
        new_category_id != ""){
      no_error_found = false;
      swWriteMessage("Please enter exactly one of the fields Gallery ID, Sub Category ID and Category ID");
    }
  }
  if (new_category_id != ""){
    if (new_subcat_id != "" ||
        new_gallery_id != ""){
      no_error_found = false;
      swWriteMessage("Please enter exactly one of the fields Gallery ID, Sub Category ID and Category ID");
    }
  }
  if (new_gallery_id == "" &&
      new_subcat_id == "" &&
      new_category_id == ""){
    no_error_found = false;
    swWriteMessage("Please enter exactly one of the fields Gallery ID, Sub Category ID and Category ID");
  }
  
  //***if filled, check that the gallery id has only numbers
  if (new_gallery_id != ""){
    var regex_result = new_gallery_id.match(/^[0-9]+$/);
    console.log(new_gallery_id);
    console.log("\"" + new_gallery_id + "\"");
    console.log("regex_result: " + regex_result);
    if (regex_result == null){
      no_error_found = false;
      swWriteMessage("Error: The Gallery ID seems invalid. It should only have numbers.");
    }
  }
  
  //***if filled, verify that gallery_id is not already assigned
  if (new_gallery_id != ""){
    if (swIsGalleryAssigned(new_gallery_id) == true){
      //tell that we can't go on because the gallery is already assigned to a section
      swWriteMessage("Error: The Gallery ID is already assigned to a Section.");
      no_error_found = false;
    }
  }
  
  return(no_error_found);

} //end of function swAssignementCreateChecks





//**************************************************
//***swDeleteAssignement
//***
//***This function deletes an assignement
//***The assignement to be deleted is passed into the
//***function by the event parameter. The parameter
//***is defined in json format. The json content can
//***be found in event.data
//**************************************************
function swDeleteAssignement(event){

  if (swSortConstants.verbose == true){
    console.log("delete assignement " + event.data.sequence_id);
  }
  
  //clear messageBox
  swClearMessageBox();

  console.dir(event);

  //find the array key of the selected sequence_id
  var del_key = null;
  for (curr_key in swSortConfig.currentJSON.detail_json_block.settings.section_assignements){
    var curr_asg = swSortConfig.currentJSON.detail_json_block.settings.section_assignements[curr_key];
    if (curr_asg.sequence_id == event.data.sequence_id){
      del_key = curr_key;
    }
  }
  
  if (swSortConstants.verbose == true){
    console.dir(swSortConfig.currentJSON.detail_json_block.settings.section_assignements);
  }
  
  //now remove (splice removes the whole key instead only setting it to null)
  swSortConfig.currentJSON.detail_json_block.settings.section_assignements.splice(del_key,1);
  
  if (swSortConstants.verbose == true){
    console.log("section assignement deleted");
    console.dir(swSortConfig.currentJSON.detail_json_block.settings.section_assignements);
  }
  
  //rebuild the assignements table
  swBuildAssignementsTable();

} //end of function swDeleteAssignement







//**************************************************
//***swMoveDefinitionUp
//***
//***This function moves a definition one step up
//***and adjusts the sequence id of the two affected
//***section definitions
//**************************************************
function swMoveDefinitionUp(event){

  if (swSortConstants.verbose == true){
    console.log("move definition up button pressed (" + event.data.section_id + ")");
  }
  
  //get the selected section definition
  var selected_def = null;
  for (curr_key in swSortConfig.currentJSON.detail_json_block.settings.section_definitions){
    
    if (swSortConfig.currentJSON.detail_json_block.settings.section_definitions[curr_key].section_id == event.data.section_id){
      //set the hit into the selected_def variable
      selected_def = swSortConfig.currentJSON.detail_json_block.settings.section_definitions[curr_key];
      //no need to search further
      break;
    }
  
  }

  if (selected_def == null){
    console.log("error: didn't find section_id: " + event.data.section_id);
  }

  //get the previous section definition
  var prev_def = null;
  var second_highest_seq = -1;
  for (curr_key in swSortConfig.currentJSON.detail_json_block.settings.section_definitions){
    
    if (swSortConfig.currentJSON.detail_json_block.settings.section_definitions[curr_key].sequence_id < selected_def.sequence_id){
      
      if (swSortConfig.currentJSON.detail_json_block.settings.section_definitions[curr_key].sequence_id > second_highest_seq){
      
        second_highest_seq = swSortConfig.currentJSON.detail_json_block.settings.section_definitions[curr_key].sequence_id;
      
        prev_def = swSortConfig.currentJSON.detail_json_block.settings.section_definitions[curr_key];
      
      }
      
    }
  
  }
  
  if (prev_def == null){
    console.log("error: didn't find a previous section for: " + event.data.section_id);
  }

  //if there is a previous section definition switch the selected and the previous
  if (prev_def != null){
  
    if (swSortConstants.verbose == true){
      console.log("previous: " + prev_def.section_id);
    }
    
    //now change the sequence_id of the selected and the previous one
    var temp_seq_id = selected_def.sequence_id;
    selected_def.sequence_id = prev_def.sequence_id;
    prev_def.sequence_id = temp_seq_id;
    
    //rebuild the Definitions Table
    swBuildDefinitionsTable();
  
  }
  
} //end of function swMoveDefinitionUp

//**************************************************
//***swMoveDefinitionDown
//***
//***This function moves a definition one step down
//***and adjusts the sequence id of the two affected
//***section definitions
//**************************************************
function swMoveDefinitionDown(event){

  if (swSortConstants.verbose == true){
    console.log("move definition down button pressed (" + event.data.section_id + ")");
  }
  
  //get the selected section definition
  var selected_def = null;
  for (curr_key in swSortConfig.currentJSON.detail_json_block.settings.section_definitions){
    
    if (swSortConfig.currentJSON.detail_json_block.settings.section_definitions[curr_key].section_id == event.data.section_id){
      //set the hit into the selected_def variable
      selected_def = swSortConfig.currentJSON.detail_json_block.settings.section_definitions[curr_key];
      //no need to search further
      break;
    }
  
  }

  if (selected_def == null){
    console.log("error: didn't find section_id: " + event.data.section_id);
  }


  //get the previous section definition
  var next_def = null;
  var next_seq = 9999; //highest value possible
  for (curr_key in swSortConfig.currentJSON.detail_json_block.settings.section_definitions){
    

    
    if (swSortConfig.currentJSON.detail_json_block.settings.section_definitions[curr_key].sequence_id > selected_def.sequence_id){

      if (swSortConfig.currentJSON.detail_json_block.settings.section_definitions[curr_key].sequence_id < next_seq){
      
        next_seq = swSortConfig.currentJSON.detail_json_block.settings.section_definitions[curr_key].sequence_id;
      
        next_def = swSortConfig.currentJSON.detail_json_block.settings.section_definitions[curr_key];
      
      }
      
    }
  
  }
  
  if (next_def == null){
    console.log("error: didn't find a next section for: " + event.data.section_id);
  }


  //if there is a next section definition switch the selected and the next one
  if (next_def != null){
  
    if (swSortConstants.verbose == true){
      console.log("next: " + next_def.section_id);
    }
    
    //now change the sequence_id of the selected and the previous one
    var temp_seq_id = selected_def.sequence_id;
    selected_def.sequence_id = next_def.sequence_id;
    next_def.sequence_id = temp_seq_id;
    
    //rebuild the Definitions Table
    swBuildDefinitionsTable();
  
  }

} //end of function swMoveDefinitionDown



//**************************************************
//***swMoveAssignementUp
//***
//***This function moves an assignement one step up
//***and adjusts the sequence id of the two affected
//***assignement
//**************************************************
function swMoveAssignementUp(event){

  if (swSortConstants.verbose == true){
    console.log("swMoveAssignementUp");
  }
  
  //get the selected assignement
  var selected_asg = null;
  for (curr_key in swSortConfig.currentJSON.detail_json_block.settings.section_assignements){
    
    if (swSortConfig.currentJSON.detail_json_block.settings.section_assignements[curr_key].sequence_id == event.data.sequence_id){
      //set the hit into the selected_def variable
      selected_asg = swSortConfig.currentJSON.detail_json_block.settings.section_assignements[curr_key];
      //no need to search further
      break;
    }
  
  }

  if (selected_asg == null){
    console.log("error: didn't find sequence_id: " + event.data.sequence_id);
  }

  //get the previous assignement
  var prev_asg = null;
  var second_highest_seq = -1;
  for (curr_key in swSortConfig.currentJSON.detail_json_block.settings.section_assignements){
    
    if (swSortConfig.currentJSON.detail_json_block.settings.section_assignements[curr_key].sequence_id < selected_asg.sequence_id){
      
      if (swSortConfig.currentJSON.detail_json_block.settings.section_assignements[curr_key].sequence_id > second_highest_seq){
      
        second_highest_seq = swSortConfig.currentJSON.detail_json_block.settings.section_assignements[curr_key].sequence_id;
      
        prev_asg = swSortConfig.currentJSON.detail_json_block.settings.section_assignements[curr_key];
      
      }
      
    }
  
  }
  
  if (prev_asg == null){
    console.log("error: didn't find a previous assignement for: " + event.data.sequence_id);
  }

  //if there is a previous assignement switch the selected and the previous
  if (prev_asg != null){
  
    if (swSortConstants.verbose == true){
      console.log("previous: " + prev_asg.sequence_id);
    }
    
    //now change the sequence_id of the selected and the previous one
    var temp_seq_id = selected_asg.sequence_id;
    selected_asg.sequence_id = prev_asg.sequence_id;
    prev_asg.sequence_id = temp_seq_id;
    
    //rebuild the Definitions Table
    swBuildAssignementsTable();
  
  }

} //end of function swMoveAssignementUp



//**************************************************
//***swMoveAssignementDown
//***
//***This function moves an assignement one step down
//***and adjusts the sequence id of the two affected
//***assignements
//**************************************************
function swMoveAssignementDown(event){

  if (swSortConstants.verbose == true){
    console.log("swMoveAssignementDown");
  }
  
  //get the selected assignement
  var selected_asg = null;
  for (curr_key in swSortConfig.currentJSON.detail_json_block.settings.section_assignements){
    
    if (swSortConfig.currentJSON.detail_json_block.settings.section_assignements[curr_key].sequence_id == event.data.sequence_id){
      //set the hit into the selected_asg variable
      selected_asg = swSortConfig.currentJSON.detail_json_block.settings.section_assignements[curr_key];
      //no need to search further
      break;
    }
  
  }

  if (selected_asg == null){
    console.log("error: didn't find sequence_id: " + event.data.sequence_id);
  }


  //get the previous assignement
  var next_asg = null;
  var next_seq = 9999; //highest value possible
  for (curr_key in swSortConfig.currentJSON.detail_json_block.settings.section_assignements){
    

    
    if (swSortConfig.currentJSON.detail_json_block.settings.section_assignements[curr_key].sequence_id > selected_asg.sequence_id){

      if (swSortConfig.currentJSON.detail_json_block.settings.section_assignements[curr_key].sequence_id < next_seq){
      
        next_seq = swSortConfig.currentJSON.detail_json_block.settings.section_assignements[curr_key].sequence_id;
      
        next_asg = swSortConfig.currentJSON.detail_json_block.settings.section_assignements[curr_key];
      
      }
      
    }
  
  }
  
  if (next_asg == null){
    console.log("error: didn't find a next assignement for: " + event.data.sequence_id);
  }


  //if there is a next assignement switch the selected and the next one
  if (next_asg != null){
  
    if (swSortConstants.verbose == true){
      console.log("next: " + next_asg.sequence_id);
    }
    
    //now change the sequence_id of the selected and the previous one
    var temp_seq_id = selected_asg.sequence_id;
    selected_asg.sequence_id = next_asg.sequence_id;
    next_asg.sequence_id = temp_seq_id;
    
    //rebuild the Definitions Table
    swBuildAssignementsTable();
  
  }

} //end of function swMoveAssignementDown




//**************************************************
//***swSaveJSONToGallery
//***
//***This function saves the (changed) JSON settings
//***into the according gallery
//**************************************************
function swSaveJSONToGallery(){

  if (swSortConstants.verbose == true){
    console.log("info: saving current JSON to gallery");
  }
  
  //swWriteToGalleryDesc(swSortConfig.currentJSON.json_gallery_id, swSortConfig.currentJSON.json_gallery_key, "changed18");
  //for testing purposes we only write into a test gallery
  
  //get the JSON from the comp object
  //var new_json = JSON.stringify(swSortConfig.currentJSON.comp_json_object);
  
  //get the JSON from the comp object and make it more readable
  var new_json = JSON.stringify(swSortConfig.currentJSON.comp_json_object, null, '\t');
  
  if (swSortConstants.verbose == true){
    console.log("new_json:");
    console.log(new_json);
  }
  
  var encoded_json = encodeURIComponent(new_json);
  
  if (swSortConstants.verbose == true){
    console.log("encoded_json:");
    console.log(encoded_json);
  }
  
  swClearMessageBox();
  
  //write into the working/example target desc
  //swWriteToGalleryDesc(18935638, "kw4vSj", encoded_json);
  
  //write into real gallery
  swWriteToGalleryDesc(swSortConfig.currentJSON.json_gallery_id, swSortConfig.currentJSON.json_gallery_key, encoded_json);
  
  swWriteMessage("Storing Configuration...please wait.");

} //end of swSaveJSONToGallery


//**************************************************
//***swWriteToGalleryDesc
//***
//***This function writes a description into a
//***specified gallery. The existing description
//***is overwritten.
//**************************************************
function swWriteToGalleryDesc(gallery_id, gallery_key, new_desc){
    
  //build data part
  var data = "tool=editDescription";
  
  data = data + "&AlbumID=" + gallery_id;
  data = data + "&AlbumKey=" + gallery_key;
  data = data + "&Description=" + new_desc;
    
  $.ajax({
    type: 'POST',
    url: "/rpc/gallery.mg",
    //data: "tool=editDescription&AlbumID=18935638&AlbumKey=kw4vSj&Description=changed",
    data: data,
    success: function(){
      //this is the callback function
      console.log("Changes saved.");
      swWriteMessage("Configuration successfully stored");
    },
    error: function(){
      //this is the error callback function
      console.log("Saving failed!!! Please save again");
      swWriteMessage("Error: Storing configuration failed. Please try again to save.");
    }
  });

} //end of swWriteToGalleryDesc



//**************************************************
//***swDeleteJSONSettingsBlock
//***
//***This function deletes the current JSON block
//***from the JSON object. After that you can save
//***and the JSON will be gone.
//***Note: If you do not save the deleted JSON will
//***be back when you reload the web page
//**************************************************
function swDeleteJSONSettingsBlock(){
  
  var idx_to_del = null;
  
  //find the index number of the current json block in the comp_json_object
  for (curr_key in swSortConfig.currentJSON.comp_json_object){
  
    var curr_json = swSortConfig.currentJSON.comp_json_object[curr_key];
    
    if (curr_json.category == swSortConfig.currentJSON.category &&
        curr_json.subcategory == swSortConfig.currentJSON.subcategory){
      idx_to_del = curr_key;
    }
  
  }
  
  if (swSortConstants.verbose == true){
    console.log("Delete Button pressed");
    console.log("idx_to_del" + idx_to_del);
    console.dir(swSortConfig.currentJSON.comp_json_object);
  }
  
  swSortConfig.currentJSON.comp_json_object.splice(idx_to_del, 1);
  
  if (swSortConstants.verbose == true){
    console.log("Configuration block deleted. Please save to confirm.");
    console.dir(swSortConfig.currentJSON.comp_json_object);
  }
  
  swClearMessageBox();
  swWriteMessage("Configuration block deleted. Please save to confirm.");
  
} //end of function swDeleteJSONSettingsBlock



//**************************************************
//***swDoesSectionDefinitionExist
//***
//***This function checks if a given section_id
//***already exists in the current settings block
//**************************************************
function swDoesSectionDefinitionExist(section_id){
  
  var exists = false;
  
  for (curr_key in swSortConfig.currentJSON.detail_json_block.settings.section_definitions){
    
    var curr_def = swSortConfig.currentJSON.detail_json_block.settings.section_definitions[curr_key];
    if (curr_def.section_id == section_id){
      exists = true;
    }
    
  }
  
  return(exists);

} //end of swDoesSectionDefinitionExist


//**************************************************
//***swIsGalleryAssigned
//***
//***This function checks if a given gallery_id
//***is already assigned to a section
//**************************************************
function swIsGalleryAssigned(gallery_id){
  
  var is_assigned = false;
  
  for (curr_key in swSortConfig.currentJSON.detail_json_block.settings.section_assignements){
  
    var curr_asg = swSortConfig.currentJSON.detail_json_block.settings.section_assignements[curr_key];
    
    if (curr_asg.gallery_id == gallery_id){
      is_assigned = true;
    }
  
  }
  
  return(is_assigned); 
  
} //end of function swIsGalleryAssigned



//**************************************************
//***swCleanupJSONObject
//***
//***This function searches for obsolet JSON blocks
//***in the comp_json_object and removes them
//**************************************************
function swCleanupJSONObject(){

  console.log("swCleanupJSONObject");
  
  swClearMessageBox();
  
  if (swSortConfig.currentJSON.comp_json_object == null){
  
    swWriteMessage("Clean Up: Nothing to do.");
  
  } else {
    
    console.log("comp_json_object before clean up:");
    console.dir(swSortConfig.currentJSON.comp_json_object);
    
    for (curr_key in swSortConfig.currentJSON.comp_json_object){
      
      var curr_json = swSortConfig.currentJSON.comp_json_object[curr_key];
      var curr_key_found = false;
      
      //now check if we find a corresponding category/subcategory in the constants
      //if we have a category/subcategory which is NOT defined in the constants
      //this is obsolet and can be deleted
      for (curr_const in swSortConstants.relevantCategories){
        
        if (swSortConstants.relevantCategories[curr_const].category == curr_json.category){
          if (swSortConstants.relevantCategories[curr_const].subcategory != null){
            if (swSortConstants.relevantCategories[curr_const].subcategory == curr_json.subcategory){
              //additionally check if the json gallery matches...if not the curr_key in comp_json_object is obsolet
              if (swSortConstants.relevantCategories[curr_const].json_gallery_id == swSortConfig.currentJSON.json_gallery_id &&
                  swSortConstants.relevantCategories[curr_const].json_gallery_key == swSortConfig.currentJSON.json_gallery_key){
                curr_key_found = true;
              }
            }
          } else {
            //no sub category defined in the constants, so a category match is enough
            //now check additionally if the json gallery matches...if not the curr_key in comp_json_object is obsolet
            if (swSortConstants.relevantCategories[curr_const].json_gallery_id == swSortConfig.currentJSON.json_gallery_id &&
                swSortConstants.relevantCategories[curr_const].json_gallery_key == swSortConfig.currentJSON.json_gallery_key){
              curr_key_found = true;
            }
          }
        }
      }
      
      //if we didn't find a corresponding block in the constants then the current json block is obsolet
      if (curr_key_found == true){
        swWriteMessage(curr_json.category + " / " + curr_json.subcategory + " found");
      } else {
        swWriteMessage(curr_json.category + " / " + curr_json.subcategory + " not found in current JSON block. So it is obsolet");
        swWriteMessage("Deleting key " + curr_key + "...");
        
        swSortConfig.currentJSON.comp_json_object.splice(curr_key, 1);
      }
      
    }
    
    console.log("comp_json_object after clean up:");
    console.dir(swSortConfig.currentJSON.comp_json_object);
  }

} //end of function swCleanupJSONObject















//**************************************************
//***submitDescription2
//***
//***This function shows how SmugMug writes a changed
//***description into the gallery (the save button
//***when you change a gallery desc)
//**************************************************
function submitDescription2(AlbumID,AlbumKey, newDescription){
  pageWorking('Saving Gallery Desc.');
  var postArray=[];
  postArray.tool='editDescription';
  postArray.AlbumID=AlbumID;
  postArray.AlbumKey=AlbumKey;
  
  //postArray.Description=YD.get('newDescription').value;
  
  postArray.Description=newDescription;
  
  ajax_query(editDescriptionRPCResult,'/rpc/gallery.mg',postArray,true);
  
}